package com.bjh.codec;

import com.bjh.model.Message;
import com.bjh.model.MessageBody;
import com.bjh.model.MessageHead;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

public class MessageDecoder extends ByteToMessageDecoder {

    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {

        //我们的请求头有7个属性，每个属性都是int型，所以占4个字节，如果小于28个字节说明这个请求数据是有问题的，
        if(in.readableBytes() < 32) {
            return;
        }

        //拿到指令
        int command = in.readInt();

        //拿到版本号
        int version = in.readInt();

        //拿到clientType
        int clientType = in.readInt();

        //拿到消息解析类型
        int messageType = in.readInt();

        //拿到imei号的长度
        int imeiLen = in.readInt();

        //拿到appId
        int appId = in.readInt();

        //拿到数据内容长度
        int bodyLen = in.readInt();

        int paramTypesLen = in.readInt();

        //我们的数据是以流的形式读取的，当读取到的数据长度小于 imei号长度+data长度，说明还没有获取到完整的请求数据，需要重新再次读取接下来TCP发送过来的数据，直到等于了就代表
        //我们已经读取到一条完整的数据了，其实这也是一种解决TCP粘包和拆包的问题
        if(in.readableBytes() < (bodyLen + imeiLen + paramTypesLen)) {
            //表示读取的数据还不够
            in.resetReaderIndex();
            return;
        }

        //通过imei号长度读取imei号
        byte[] imeiData = new byte[imeiLen];
        in.readBytes(imeiData);
        String imei = new String(imeiData);

        //通过bodyLen读取数据内容
        byte[] bodyData = new byte[bodyLen];
        in.readBytes(bodyData);

        //读取类型长度
        byte[] paramsTypes = new byte[paramTypesLen];
        in.readBytes(paramsTypes);

        List list = objectMapper.readValue(paramsTypes, List.class);
        /**
         * 设置请求头
         */
        MessageHead messageHead = new MessageHead();
        messageHead.setCommond(command);
        messageHead.setAppId(appId);
        messageHead.setBodyLen(bodyData.length);
        messageHead.setImeiLen(imeiData.length);
        messageHead.setVersion(version);
        messageHead.setClientType(clientType);
        messageHead.setMessageType(messageType);
        messageHead.setParamsTypeLen(paramTypesLen);
        /**
         * 设置请求体
         */
        MessageBody messageBody = new MessageBody();
        messageBody.setImei(imei);
        messageBody.setParams(list);
        Message message = new Message();
        message.setMessageHead(messageHead);
        /**
         * 根据messageType来封装请求数据
         */
        if(messageType == 0x0) {
            //解析成JSON格式
            String body = new String(bodyData);
            com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
            jsonObject.put("body",body);
            messageBody.setData(jsonObject);
        }else if(messageType == 0x1) {
            //解析成Protobuf
        }else if(messageType == 0x2) {
            //解析成Xml
        }
        message.setMessageBody(messageBody);

        //更新读索引
        in.markReaderIndex();

        //最后通过管道写出去
        out.add(message);
    }
}
